package com.zenithmind.exam.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.exam.mapper.WrongQuestionMapper;
import com.zenithmind.exam.pojo.entity.WrongQuestion;
import com.zenithmind.exam.pojo.vo.QuestionVO;
import com.zenithmind.exam.service.QuestionService;
import com.zenithmind.exam.service.WrongQuestionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 错题本服务实现类
 * 
 * @author ZenithMind
 * @since 2024-07-01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WrongQuestionServiceImpl extends ServiceImpl<WrongQuestionMapper, WrongQuestion> implements WrongQuestionService {

    private final WrongQuestionMapper wrongQuestionMapper;
    private final QuestionService questionService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addWrongQuestion(String userId, String questionId, String examRecordId) {
        try {
            // 检查是否已存在
            WrongQuestion existingWrong = wrongQuestionMapper.selectByUserIdAndQuestionId(userId, questionId);
            
            if (existingWrong != null) {
                // 如果已存在，增加错误次数
                int result = wrongQuestionMapper.incrementWrongCount(userId, questionId);
                if (result > 0) {
                    log.info("增加错题次数成功，用户ID: {}, 题目ID: {}", userId, questionId);
                }
                return result > 0;
            } else {
                // 新增错题记录
                WrongQuestion wrongQuestion = new WrongQuestion();
                wrongQuestion.setUserId(userId);
                wrongQuestion.setQuestionId(questionId);
                wrongQuestion.setExamRecordId(examRecordId);
                wrongQuestion.setWrongCount(1);
                wrongQuestion.setLastWrongTime(LocalDateTime.now());
                wrongQuestion.setIsMastered(0);
                wrongQuestion.setCreateTime(LocalDateTime.now());
                wrongQuestion.setUpdateTime(LocalDateTime.now());

                boolean result = save(wrongQuestion);
                if (result) {
                    log.info("添加错题成功，用户ID: {}, 题目ID: {}", userId, questionId);
                }
                return result;
            }
        } catch (Exception e) {
            log.error("添加错题失败", e);
            throw new BusinessException("添加错题失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean markAsMastered(String userId, String questionId) {
        try {
            int result = wrongQuestionMapper.markAsMastered(userId, questionId);
            if (result > 0) {
                log.info("标记题目为已掌握成功，用户ID: {}, 题目ID: {}", userId, questionId);
            }
            return result > 0;
        } catch (Exception e) {
            log.error("标记题目为已掌握失败", e);
            throw new BusinessException("标记题目为已掌握失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean markAsNotMastered(String userId, String questionId) {
        try {
            int result = wrongQuestionMapper.markAsNotMastered(userId, questionId);
            if (result > 0) {
                log.info("标记题目为未掌握成功，用户ID: {}, 题目ID: {}", userId, questionId);
            }
            return result > 0;
        } catch (Exception e) {
            log.error("标记题目为未掌握失败", e);
            throw new BusinessException("标记题目为未掌握失败: " + e.getMessage());
        }
    }

    @Override
    public List<QuestionVO> getUserWrongQuestions(String userId) {
        List<WrongQuestion> wrongQuestions = wrongQuestionMapper.selectByUserId(userId);
        return convertToQuestionVOList(wrongQuestions);
    }

    @Override
    public List<QuestionVO> getUserMasteredQuestions(String userId) {
        List<WrongQuestion> masteredQuestions = wrongQuestionMapper.selectMasteredByUserId(userId);
        return convertToQuestionVOList(masteredQuestions);
    }

    @Override
    public IPage<QuestionVO> getUserWrongQuestionPage(Page<WrongQuestion> page, String userId, Integer isMastered) {
        IPage<WrongQuestion> wrongQuestionPage = wrongQuestionMapper.selectWrongQuestionPage(page, userId, isMastered);
        
        IPage<QuestionVO> voPage = new Page<>();
        voPage.setCurrent(wrongQuestionPage.getCurrent());
        voPage.setSize(wrongQuestionPage.getSize());
        voPage.setTotal(wrongQuestionPage.getTotal());
        voPage.setPages(wrongQuestionPage.getPages());
        
        List<QuestionVO> voList = convertToQuestionVOList(wrongQuestionPage.getRecords());
        voPage.setRecords(voList);
        
        return voPage;
    }

    @Override
    public Integer countUserWrongQuestions(String userId, Integer isMastered) {
        return wrongQuestionMapper.countByUserIdAndMastered(userId, isMastered);
    }

    @Override
    public List<QuestionVO> getFrequentWrongQuestions(String userId, Integer limit) {
        List<WrongQuestion> wrongQuestions = wrongQuestionMapper.selectFrequentWrongQuestions(userId, limit);
        return convertToQuestionVOList(wrongQuestions);
    }

    @Override
    public List<QuestionVO> getRecentWrongQuestions(String userId, Integer limit) {
        List<WrongQuestion> wrongQuestions = wrongQuestionMapper.selectRecentWrongQuestions(userId, limit);
        return convertToQuestionVOList(wrongQuestions);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean clearUserWrongQuestions(String userId) {
        try {
            int result = wrongQuestionMapper.deleteByUserId(userId);
            if (result > 0) {
                log.info("清空用户错题本成功，用户ID: {}, 清空数量: {}", userId, result);
            }
            return result > 0;
        } catch (Exception e) {
            log.error("清空用户错题本失败", e);
            throw new BusinessException("清空用户错题本失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchMarkAsMastered(String userId, List<String> questionIds) {
        try {
            int successCount = 0;
            for (String questionId : questionIds) {
                int result = wrongQuestionMapper.markAsMastered(userId, questionId);
                if (result > 0) {
                    successCount++;
                }
            }
            
            log.info("批量标记为已掌握完成，用户ID: {}, 成功数量: {}/{}", userId, successCount, questionIds.size());
            return successCount > 0;
        } catch (Exception e) {
            log.error("批量标记为已掌握失败", e);
            throw new BusinessException("批量标记为已掌握失败: " + e.getMessage());
        }
    }

    @Override
    public List<String> getUserWrongQuestionIds(String userId, Integer isMastered) {
        return wrongQuestionMapper.selectQuestionIdsByUserId(userId, isMastered);
    }

    @Override
    public Integer getQuestionWrongCount(String questionId) {
        return wrongQuestionMapper.sumWrongCountByQuestionId(questionId);
    }

    @Override
    public List<QuestionVO> generateWrongQuestionPractice(String userId, Integer count) {
        try {
            // 获取用户的错题列表，优先选择高频错题
            List<WrongQuestion> wrongQuestions = wrongQuestionMapper.selectFrequentWrongQuestions(userId, count * 2);
            
            if (wrongQuestions.isEmpty()) {
                return Collections.emptyList();
            }
            
            // 随机选择指定数量的题目
            Collections.shuffle(wrongQuestions);
            List<WrongQuestion> selectedQuestions = wrongQuestions.stream()
                    .limit(count)
                    .collect(Collectors.toList());
            
            List<QuestionVO> practiceQuestions = convertToQuestionVOList(selectedQuestions);
            
            log.info("生成错题练习成功，用户ID: {}, 题目数量: {}", userId, practiceQuestions.size());
            return practiceQuestions;
        } catch (Exception e) {
            log.error("生成错题练习失败", e);
            throw new BusinessException("生成错题练习失败: " + e.getMessage());
        }
    }

    @Override
    public WrongQuestion getWrongQuestionStatistics(String userId) {
        try {
            WrongQuestion statistics = new WrongQuestion();
            statistics.setUserId(userId);
            
            // 统计未掌握的错题数量
            Integer notMasteredCount = countUserWrongQuestions(userId, 0);
            statistics.setWrongCount(notMasteredCount);
            
            // 统计已掌握的错题数量
            Integer masteredCount = countUserWrongQuestions(userId, 1);
            // 可以用其他字段来存储已掌握数量，这里简单处理
            
            log.info("获取错题统计成功，用户ID: {}, 未掌握: {}, 已掌握: {}", userId, notMasteredCount, masteredCount);
            return statistics;
        } catch (Exception e) {
            log.error("获取错题统计失败", e);
            throw new BusinessException("获取错题统计失败: " + e.getMessage());
        }
    }

    /**
     * 转换错题记录列表为题目VO列表
     */
    private List<QuestionVO> convertToQuestionVOList(List<WrongQuestion> wrongQuestions) {
        return wrongQuestions.stream()
                .map(wrongQuestion -> {
                    QuestionVO questionVO = questionService.getQuestionById(wrongQuestion.getQuestionId(), false);
                    if (questionVO != null) {
                        // 添加错题相关信息
                        questionVO.setWrongCount(wrongQuestion.getWrongCount());
                        questionVO.setLastWrongTime(wrongQuestion.getLastWrongTime());
                        questionVO.setIsMastered(wrongQuestion.getIsMastered() == 1);
                    }
                    return questionVO;
                })
                .filter(questionVO -> questionVO != null)
                .collect(Collectors.toList());
    }
}
